﻿using FreeSql.Internal.ObjectPool;
using K4os.Hash.xxHash;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using PropertyManagementSystemAPI.Models;
using System.Data.Common;

namespace PropertyManagementSystemAPI.Controllers
{
    /// <summary>
    /// 车位使用信息管理
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class ParkingUseInfoController : ControllerBase
    {
        private readonly IFreeSql db;
        public ParkingUseInfoController(IFreeSql _db)
        {
            this.db = _db;
        }

        /// <summary>
        /// 获取车位使用管理信息
        /// </summary>
        /// <param name="page">页数</param>
        /// <param name="limit">页条数</param>
        /// <param name="state">状态</param>
        /// <param name="strName"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult getParkingUseInfo(int page, int limit, int state, string? strName)
        {
            bool stateRes = state == 1 ? true : false;
            var list = db.Select<Parkinguseinfo, Parkingpriceinfo, Ownerinfo, Parkingspaceinfo>()
                .LeftJoin((a, b, c, d) => a.Priceid == b.Priceid && b.Isdelete == false)
                .LeftJoin((a, b, c, d) => a.Oid == c.Oid && c.Isdelete == false)
                .LeftJoin((a, b, c, d) => a.Pid == d.Pid && d.Pdelete == false)
            .Where((a, b, c, d) => ((state == 2) || (b.Usetype == stateRes)) && a.Isdelete == false)
            .Count(out var total)
            .Page(page, limit)
            .ToList((a, b, c, d) => new
            {
                a.Useid,
                a.Pid,
                a.Oid,
                a.Priceid,
                a.Useendtime,
                a.Usestarttime,
                a.Createtime,
                a.Isdelete,
                b.Usetype,
                b.Useprice,
                c.Orealname,
                d.Pname,
                d.Pnumber
            });

            var json = new
            {
                code = 200,
                data = list,
                total = total
            };
            return Ok(json);
        }

        /// <summary>
        /// 添加车位使用信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> addInfo([FromBody] Parkinguseinfo info)
        {
            using Object<DbConnection> conn = db.Ado.MasterPool.Get();
            using DbTransaction transaction = conn.Value.BeginTransaction();
            bool res = false;
            try
            {
                info.Createtime = DateTime.Now;
                await db.Insert(info)
                .WithTransaction(transaction)
                .ExecuteAffrowsAsync();

                await db.Update<Parkingspaceinfo>(info.Pid)
                    .Set(a => a.Pstate == true)
                    .WithTransaction(transaction)
                    .ExecuteAffrowsAsync();

                res = true;
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                res = false;
            }
            return Ok(res);
        }

        /// <summary>
        /// 编辑车位使用信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<IActionResult> editInfo([FromBody] Parkinguseinfo info)
        {
            using Object<DbConnection> conn = db.Ado.MasterPool.Get();
            using DbTransaction transaction = conn.Value.BeginTransaction();
            bool res = false;
            try
            {
                Parkinguseinfo oldInfo = await db.Select<Parkinguseinfo>().Where(a => a.Useid == info.Useid).FirstAsync();
                await db.Update<Parkinguseinfo>().SetSource(info).WithTransaction(transaction).ExecuteAffrowsAsync();

                //判断是否更改了车位，若更改了，则先将之前的车位状态信息调整为空闲，然后再将重新更改的车位信息调整为使用
                if (oldInfo.Pid != info.Pid)
                {

                    await db.Update<Parkingspaceinfo>(oldInfo.Pid)
                    .Set(a => a.Pstate == false)
                    .WithTransaction(transaction)
                    .ExecuteAffrowsAsync();

                    await db.Update<Parkingspaceinfo>(info.Pid)
                    .Set(a => a.Pstate == true)
                    .WithTransaction(transaction)
                    .ExecuteAffrowsAsync();
                }
                res = true;
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                res = false;
            }
            return Ok(res);
        }

        /// <summary>
        /// 删除车位使用信息
        /// </summary>
        /// <param name="userid">车位使用id</param>
        /// <param name="pid">车位id</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<IActionResult> deleteInfo(int userid, int pid)
        {
            using Object<DbConnection> conn = db.Ado.MasterPool.Get();
            using DbTransaction transaction = conn.Value.BeginTransaction();
            bool res = false;
            try
            {
                //删除当前使用信息
                await db.Update<Parkinguseinfo>(userid)
                    .Set(a => a.Isdelete == true)
                    .WithTransaction(transaction)
                    .ExecuteAffrowsAsync();

                //设置车位为空闲
                await db.Update<Parkingspaceinfo>(pid)
                    .Set(a => a.Pstate == false)
                    .WithTransaction(transaction)
                    .ExecuteAffrowsAsync();

                res = true;
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                res = false;
            }
            return Ok(res);
        }
    }
}
